namespace Pool {
    export class SharedPool {
        private static _pool: Object = {};

        public static getObject<T extends any>(classz: new () => T): T {
            const document_class = classz.prototype.__class__;
            var result;
            var arr = this._pool[document_class];
            if (arr && arr.length) {
                result = arr.pop();
            }
            else {
                result = new classz();
                result.key = document_class;
            }

            return result;
        }

        public static disposeObject(obj: any) {
            var key: string = obj.key;
            if (!this._pool[key]) {
                this._pool[key] = [];
            }

            this._pool[key].push(obj);
        }

        public static clearObject(classz: new () => any) {
            const document_class = classz.prototype.__class__;
            delete this._pool[document_class];
        }
    }

    //可以手动添加对象入池
    export class ObjectPool<T extends any>
    {
        private _pool: T[];
        private classz: new () => T;

        constructor(classz: new () => T) {
            this.classz = classz;
            this._pool = [];
        }

        public tryGet() {
            if (this._pool.length > 0) {
                return this._pool.pop();
            }
            return null;
        }
        public get() {
            let obj: T;
            if (this._pool.length > 0) {
                obj = this._pool.pop();
            }
            else {
                obj = new this.classz();
            }
            return obj;
        }

        public dispose(obj: T) {
            if (obj.onDispose) {
                obj.onDispose();
            }
            // if (obj.dispose) {
            //     obj.dispose();
            // }
            this._pool.push(obj);
        }
    }

    //会缓存已分配的对象
    export class CachedPool<T extends any> extends ObjectPool<T>
    {
        private _list: T[];
        constructor(classz: new () => T) {
            super(classz);
            this._list = [];
        }

        public get() {
            const obj = super.get();
            this._list.push(obj);
            return obj;
        }

        public dispose(obj: T) {
            super.dispose(obj);
            const index = this._list.indexOf(obj);
            if (index !== -1) {
                this._list.splice(index, 1);
            }
        }

        public disposeAll() {
            const list = this._list;
            this._list = [];
            list.forEach(v => {
                super.dispose(v);
            });
        }
    }
}